﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using BlueLotus7.Common;

namespace BlueLotus7.ArchiveSystem.SinaContentApi
{
    public class ContentRetriever
    {
        protected string loginUserName = string.Empty;
        protected string loginPassword = string.Empty;
        protected bool hasLogined = false;
        protected string gsid = null;
        protected CookieContainer cookieContainer = new CookieContainer();
        protected const string loginPageUrl = "http://3g.sina.com.cn/prog/wapsite/sso/login.php?backURL=http%3A%2F%2Fweibo.cn%2Fdpool%2Fttt%2Fhome.php%3Fs2w%3Dlogin&backTitle=%D0%C2%C0%CB%CE%A2%B2%A9&vt=4&ns=1&pt=1";
        protected const string loginSubmitUrl = "http://3g.sina.com.cn/prog/wapsite/sso/login_submit.php?rand=693538431&backURL=http%3A%2F%2Fweibo.cn%2Fdpool%2Fttt%2Fhome.php%3Fs2w%3Dlogin&backTitle=%D0%C2%C0%CB%CE%A2%B2%A9&vt=4&ns=1";
        protected const string key_PasswordName = "PasswordName";
        protected const string key_VK = "VK";

        public bool HasLogined
        {
            get
            {
                return this.hasLogined;
            }
        }

        public ContentRetriever(string loginUserName, string loginPassword)
        {
            this.loginUserName = loginUserName;
            this.loginPassword = loginPassword;
        }

        public void TryLogin()
        {
            this.gsid = string.Empty;

            Dictionary<string, string> hiddenParameters = null;
            HttpWebRequest request = null;
            string registerUrl = null;

            try
            {
                request = (HttpWebRequest)HttpWebRequest.Create(loginPageUrl);
                request.CookieContainer = this.cookieContainer;

                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    string content = ReadTextFromResponse(response, Encoding.UTF8);

                    hiddenParameters = new Dictionary<string, string>();
                    int index = content.IndexOf("password_");
                    int endIndex = content.IndexOf('"', index);
                    hiddenParameters.Add(key_PasswordName, content.Substring(index, endIndex - index));

                    index = content.IndexOf("name=\"vk\"");
                    index = content.IndexOf("value", index);
                    index = content.IndexOf('"', index);
                    endIndex = content.IndexOf('"', index + 1);
                    hiddenParameters.Add(key_VK, content.Substring(index + 1, endIndex - 1 - index));
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Fail to get hidden parameters", ex);
            }

            if (hiddenParameters != null)
            {

                request = (HttpWebRequest)HttpWebRequest.Create(loginSubmitUrl);
                StringBuilder postBuilder = new StringBuilder();
                postBuilder.Append("mobile=" + loginUserName);
                postBuilder.Append("&" + hiddenParameters[key_PasswordName] + "=" + loginPassword);

                postBuilder.Append("&backURL=http%3A%2F%2Fweibo.cn%2Fdpool%2Fttt%2Fhome.php?s2w=login");
                postBuilder.Append("&backTitle=%E6%96%B0%E6%B5%AA%E5%BE%AE%E5%8D%9A");
                postBuilder.Append("&backURL=http%3A%2F%2Fweibo.cn%2Fdpool%2Fttt%2Fhome.php?s2w=login");
                postBuilder.Append("&vk=" + hiddenParameters[key_VK]);
                postBuilder.Append("&submit=%E7%99%BB%E5%BD%95");
                ASCIIEncoding encoding = new ASCIIEncoding();
                byte[] data = encoding.GetBytes(postBuilder.ToString());

                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = data.Length;
                Stream stream = request.GetRequestStream();
                stream.Write(data, 0, data.Length);
                stream.Close();
                request.CookieContainer = this.cookieContainer;
                request.Referer = loginPageUrl;
                request.KeepAlive = true;
                request.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; BOIE9;ZHCN)";
                request.Accept = "*/*";

                try
                {
                    using (WebResponse response = request.GetResponse())
                    {
                        string content = ReadTextFromResponse(response, Encoding.UTF8);
                        int index = content.IndexOf("http://weibo.cn/dpool/ttt/crossDomain.php");
                        if (index > -1)
                        {
                            int endIndex = content.IndexOf('"', index);
                            registerUrl = content.Substring(index, endIndex - index);

                        }
                        else
                        {
                            throw new Exception("Fail to login for wrong account info.");
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception("Fail to login Sina3G.", ex);
                }

                if (!string.IsNullOrWhiteSpace(registerUrl))
                {
                    int index = registerUrl.IndexOf("g=");
                    int endIndex = registerUrl.IndexOf('&', index);
                    this.gsid = registerUrl.Substring(index + 2, endIndex - index - 2);


                    request = (HttpWebRequest)HttpWebRequest.Create(registerUrl);
                    request.CookieContainer = this.cookieContainer;
                    request.GetResponse();

                    this.hasLogined = true;
                }
            }
        }

        protected string AppendGSID(string originalUrl)
        {
            if (!string.IsNullOrWhiteSpace(originalUrl))
            {
                if (originalUrl.IndexOf('?') < 0)
                {
                    originalUrl += "?gsid=" + (this.gsid == null ? string.Empty : gsid);
                }
                else
                {
                    originalUrl += "&gsid=" + (this.gsid == null ? string.Empty : gsid);
                }
            }

            return originalUrl;
        }

        protected string RetrieveContentByUrl(string url)
        {
            return RetrieveContentByUrl(url, null, null);
        }

        protected string RetrieveContentByUrl(string url, Dictionary<string, string> postDatas, string refer)
        {
            string content = string.Empty;

            if (!string.IsNullOrWhiteSpace(url))
            {
                url = AppendGSID(url);
                bool hasPostData = postDatas != null && postDatas.Keys.Count > 0;

                if (string.IsNullOrWhiteSpace(refer))
                {
                    refer = "http://www.weibo.cn";
                }

                try
                {
                    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
                    request.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; BOIE9;ZHCN)";
                    request.Method = hasPostData ? "POST" : "GET";
                    request.Accept = "*/*";
                    request.Referer = refer;
                    request.CookieContainer = this.cookieContainer;

                    if (hasPostData)
                    {
                        WebUtil.Instance.FillPostDataOnHttpWebRequest(request, postDatas);
                    }

                    content = ReadTextFromResponse(request.GetResponse(), Encoding.UTF8);
                }
                catch { }
            }

            return content;
        }

        protected string ReadTextFromResponse(WebResponse response, Encoding encoding)
        {
            return WebUtil.Instance.ReadTextFromResponse(response, encoding);
        }
    }
}
